package ${packagePrefix}.common.api;

import ${packagePrefix}.common.exception.ErrorCode;
import com.fasterxml.jackson.annotation.JsonFormat;

import java.io.Serializable;
import java.time.LocalDateTime;

<#if generateComments>
/**
 * 统一API响应结果
 * <p>所有接口统一返回格式，提供成功和失败的静态构建方法</p>
 *
 * @author Auto Generated
 */
</#if>
public class ApiResponse<T> implements Serializable {

    private static final long serialVersionUID = 1L;
    
    /**
     * 是否成功
     */
    private boolean success;
    
    /**
     * 响应码
     */
    private String code;
    
    /**
     * 响应消息
     */
    private String message;
    
    /**
     * 响应数据
     */
    private T data;
    
    /**
     * 响应时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime timestamp;
    
    /**
     * 请求路径
     */
    private String path;
    
    /**
     * 追踪ID
     */
    private String traceId;

    public ApiResponse() {
        this.timestamp = LocalDateTime.now();
    }
    
    /**
     * 构建成功响应
     *
     * @param <T> 数据类型
     * @return 成功响应
     */
    public static <T> ApiResponse<T> success() {
        ApiResponse<T> response = new ApiResponse<>();
        response.setSuccess(true);
        response.setCode(ErrorCode.SUCCESS.getCode());
        response.setMessage(ErrorCode.SUCCESS.getMessage());
        return response;
    }
    
    /**
     * 构建带数据的成功响应
     *
     * @param data 响应数据
     * @param <T>  数据类型
     * @return 成功响应
     */
    public static <T> ApiResponse<T> success(T data) {
        ApiResponse<T> response = success();
        response.setData(data);
        return response;
    }
    
    /**
     * 构建带数据和消息的成功响应
     *
     * @param data    响应数据
     * @param message 响应消息
     * @param <T>     数据类型
     * @return 成功响应
     */
    public static <T> ApiResponse<T> success(T data, String message) {
        ApiResponse<T> response = success(data);
        response.setMessage(message);
        return response;
    }
    
    /**
     * 构建失败响应
     *
     * @param errorCode 错误码
     * @param <T>       数据类型
     * @return 失败响应
     */
    public static <T> ApiResponse<T> fail(ErrorCode errorCode) {
        ApiResponse<T> response = new ApiResponse<>();
        response.setSuccess(false);
        response.setCode(errorCode.getCode());
        response.setMessage(errorCode.getMessage());
        return response;
    }
    
    /**
     * 构建带自定义消息的失败响应
     *
     * @param errorCode    错误码
     * @param customMessage 自定义消息
     * @param <T>          数据类型
     * @return 失败响应
     */
    public static <T> ApiResponse<T> fail(ErrorCode errorCode, String customMessage) {
        ApiResponse<T> response = fail(errorCode);
        response.setMessage(customMessage);
        return response;
    }
    
    /**
     * 设置请求路径
     *
     * @param path 请求路径
     * @return 当前响应对象
     */
    public ApiResponse<T> path(String path) {
        this.path = path;
        return this;
    }
    
    /**
     * 设置追踪ID
     *
     * @param traceId 追踪ID
     * @return 当前响应对象
     */
    public ApiResponse<T> traceId(String traceId) {
        this.traceId = traceId;
        return this;
    }
    
    // Getters and Setters
    public boolean isSuccess() {
        return success;
    }

    public void setSuccess(boolean success) {
        this.success = success;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    public LocalDateTime getTimestamp() {
        return timestamp;
    }

    public void setTimestamp(LocalDateTime timestamp) {
        this.timestamp = timestamp;
    }

    public String getPath() {
        return path;
    }

    public void setPath(String path) {
        this.path = path;
    }

    public String getTraceId() {
        return traceId;
    }

    public void setTraceId(String traceId) {
        this.traceId = traceId;
    }
} 